package br.com.esporte.negocios.controlador.imp;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;

import br.com.esporte.negocios.controlador.IService;
import br.com.esporte.negocios.entidade.imp.Entidade;
import br.com.esporte.negocios.entidade.imp.Usuario;
import br.com.esporte.repositorio.DAO.IGenericDAO;
import br.com.esporte.repositorio.filtro.IFiltro;

public abstract class GenericoService<ENTIDADE extends Entidade, ID extends Serializable, FILTRO extends IFiltro, REPOSITORIO extends IGenericDAO<ENTIDADE, ID, FILTRO>> implements IService<ENTIDADE, ID, FILTRO, REPOSITORIO> {

	private REPOSITORIO repositorioDAO;

	public GenericoService(REPOSITORIO repositorioDAO) {
		this.repositorioDAO = repositorioDAO;
	}

	@Override
	public void alterar(ENTIDADE vo, Usuario usuario) {
		this.tratarDadosEntidade(vo);
		this.validarAlteracao(vo);
		this.validarUnicidade(vo);
		vo.setDataAlteracao(new Date(System.currentTimeMillis()));
		vo.setUsuarioAlteracao(usuario);
		this.resolverPerDependencias(vo, usuario);
		this.repositorioDAO.alterar(vo);
		this.resolverPosDependencias(vo, usuario);
	}

	@Override
	public ENTIDADE buscar(ID id) {
		return this.repositorioDAO.buscar(id);
	}

	@Override
	public Collection<ENTIDADE> consultar(FILTRO filtro) {
		return this.repositorioDAO.consultar(filtro);
	}

	@Override
	public REPOSITORIO getRepositorioDAO() {
		return this.repositorioDAO;
	}

	@Override
	public void inserir(ENTIDADE vo, Usuario usuario) {
		this.tratarDadosEntidade(vo);
		this.validarInclusao(vo);
		this.validarUnicidade(vo);
		vo.setDataAlteracao(new Date(System.currentTimeMillis()));
		vo.setDataInclusao(new Date(System.currentTimeMillis()));
		vo.setUsuarioInclusao(usuario);
		vo.setUsuarioAlteracao(usuario);
		this.resolverPerDependencias(vo, usuario);
		this.repositorioDAO.inserir(vo);
		this.resolverPosDependencias(vo, usuario);
	}

	@Override
	public ENTIDADE load(ID id) {
		return this.repositorioDAO.load(id);
	}

	@Override
	public void remover(ENTIDADE vo) {
		this.repositorioDAO.remover(vo);
	}

	@Override
	public abstract void resolverPerDependencias(ENTIDADE vo, Usuario usuario);

	@Override
	public abstract void resolverPosDependencias(ENTIDADE vo, Usuario usuario);

	public abstract void tratarDadosEntidade(ENTIDADE vo);

	@Override
	public abstract void validarAlteracao(ENTIDADE vo);

	@Override
	public abstract void validarExclusao(ENTIDADE vo);

	@Override
	public abstract void validarInclusao(ENTIDADE vo);

	@Override
	public abstract void validarUnicidade(ENTIDADE vo);

}
